匹配几何效果(matchedGeometryEffect)
matchedGeometryEffect 用于在 不同视图之间建立几何关联关系,使视图在:
- 位置变化
- 尺寸变化
- 布局层级变化
- 条件渲染切换
这些场景中,仍然保持 连续、平滑、空间一致的动画过渡效果。
该能力对应 SwiftUI 中的 matchedGeometryEffect,属于 组件级几何联动动画系统,不依赖导航系统。
一、API 定义
二、核心作用
matchedGeometryEffect 的核心作用是:
让两个“逻辑上是同一个元素”的视图,在 不同布局结构中共享几何信息,从而产生连续的过渡动画。
它解决的问题包括:
- 视图从一个容器移动到另一个容器时的“跳变”
- 视图尺寸变化时的“突变”
- 列表项展开为详情页时的“断层感”
- Tab 切换指示器的“瞬移感”
三、参数详解
1. id(几何匹配唯一标识)
-
用于标识这是 哪一个几何元素
-
在同一个
namespace下:- id 相同的视图才会参与几何匹配
-
通常来自:
- 数据模型 ID
- 索引值
- 业务唯一标识
规则:
-
id 必须稳定
-
动画期间不能频繁变化
-
同一时刻:
- 一个 id 只能有一个
isSource = true
- 一个 id 只能有一个
2. namespace(几何命名空间)
-
用于将多个匹配动画分组隔离
-
不同 namespace 之间:
- 即使 id 相同,也不会产生动画
-
必须由
NamespaceReader创建并注入
规则:
- source 与 target 必须使用 同一个 namespace
- 不允许跨 namespace 匹配
3. properties(参与匹配的几何属性)
默认值:
含义说明:
选择原则:
"frame":最完整、最自然的动画"position":指示器、滑块、选中背景"size":放大缩小、展开收起
4. anchor(锚点)
默认值:
作用:
-
决定动画进行时:
- 元素是从哪个相对位置进行对齐和计算的
常见取值:
"center""topLeading""topTrailing""bottomLeading""bottomTrailing"
使用场景:
- 卡片从左上角展开
- 头像从右上角放大
- 底部元素向上弹出
5. isSource(是否作为几何数据的“源”)
默认值:
含义说明:
标准使用模式:
- 原始视图:
isSource = true - 目标视图:
isSource = false
如果省略:
- 第一个出现的视图默认作为 source
- 其余作为接收方
四、最小可用示例(位置 + 尺寸联动)
该示例演示: 一个圆形在两个区域之间切换位置与尺寸,并保持连续动画。
该示例实现的动画效果:
-
同一个圆:
- 从上方小尺寸区域
- 平滑移动并放大到下方大区域
-
无跳变、无突变、无瞬移
五、仅同步“位置”的示例(指示器动画)
适用于:
- Tab 选中动画
- 滑块指示器
- 选中背景平移
六、仅同步“尺寸”的示例(放大缩小)
适用于:
- 头像放大
- 卡片展开
- 按钮按压动画
七、多元素联动示例(卡片 → 详情)
效果说明:
- 图片与标题同时参与几何匹配
- 从卡片形态平滑过渡为详情页布局
- 无需使用导航动画
八、关键使用规则总结
-
namespace 必须完全相同
-
id 必须完全一致
-
同一时刻:
- 一个 id 只能有一个
isSource = true
- 一个 id 只能有一个
-
默认行为:
-
source 与 target 必须:
- 同一渲染周期内完成切换
-
如果 source 和 target:
- 同时存在,且都为
isSource = true→ 动画不确定,可能失效
- 同时存在,且都为
-
Widget 与 Live Activity 环境不支持完整 matchedGeometry 动画能力
九、适用场景总结
适合使用 matchedGeometryEffect 的场景:
- Tab 指示器动画
- 卡片 → 详情展开
- 图片放大预览
- 列表项选中动画
- 分栏布局中的选中项切换
不适合使用的场景:
- 高频数据刷新列表
- 大量同时进行几何动画的复杂视图树
- 帧率敏感的实时图表
